package cn.trymore.core.vo;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.trymore.core.util.UtilReflect;

public class VoTplExcelField 
{
	private boolean isTitle = false;
	private boolean paramInfieldText = false;
	private int fieldRowSpan = VoTplExcelObj.DEFAULT_COLUMN_ROWSPAN;
	private String fieldCell = null;
	private String fieldText = null;
	private String fieldKeyData = null;
	private String fieldKeyComment = null;
	private String fieldDescription = null;
	
	public VoTplExcelField () 
	{ 
	}
	
	public VoTplExcelField 
	(
			boolean isTitle, 
			String fieldCell, 
			String fieldText, 
			String fieldKeyData) {
		this(isTitle, fieldCell, fieldText, fieldKeyData, null);
	}
	
	public VoTplExcelField (
			boolean isTitle, 
			String fieldCell, 
			String fieldText, 
			String fieldKeyData, 
			String fieldKeyComment) 
	{
		this(isTitle, fieldCell, fieldText, fieldKeyData, fieldKeyComment, null, VoTplExcelObj.DEFAULT_COLUMN_ROWSPAN);
	}
	
	public VoTplExcelField (
			boolean isTitle, 
			String fieldCell, 
			String fieldText, 
			String fieldKeyData, 
			String fieldKeyComment, 
			String fieldDescription, 
			int fieldRowSpan) 
	{
		this.isTitle = isTitle;
		this.fieldCell = fieldCell;
		this.fieldText = fieldText;
		this.fieldKeyData = fieldKeyData;
		this.fieldKeyComment = fieldKeyComment;
		this.fieldDescription = fieldDescription;
		this.fieldRowSpan = fieldRowSpan;
	}
	
	public static List<VoTplExcelField> fromXmlNodeList(NodeList nodes, 
			List<Map<String, Object>> dynamicData) 
	{
		if (nodes != null) 
		{
			Node node = nodes.item(0);
			if (node.getChildNodes() != null && node.getChildNodes().getLength() > 0) 
			{
				NodeList childs = node.getChildNodes();
				List<VoTplExcelField> vtobjList = new ArrayList<VoTplExcelField>();
				for (int i = 0, len = childs.getLength(); i < len; i++) 
				{
					List<VoTplExcelField> data = fromXmlNode(childs.item(i), dynamicData);
					if (data != null) 
					{
						vtobjList.addAll(data);
					}
				}
				return vtobjList;
			}
		}
		return null;
	}
	
	@SuppressWarnings("unused")
	public static List<VoTplExcelField> fromXmlNode(Node node,
			List<Map<String, Object>> dynamicData) 
	{
		if (node != null) 
		{
			if (node.getNodeName().equals("field-column-dynamic"))
			{
				List<VoTplExcelField> vtobjs = new ArrayList<VoTplExcelField>();
				
				NodeList childs = node.getChildNodes();
				if (childs != null && childs.getLength() > 0) 
				{
					int count = 0;
					HashMap<String, Object> objcmp = new HashMap<String, Object>();
					for (Map<String, Object> item : dynamicData)
					{
						objcmp.clear();
						
						for (Entry<String, Object> entry : item.entrySet()) 
						{
							objcmp.putAll(UtilReflect.getAllComponentsName(
									entry.getKey() + ".", entry.getValue()));
						}
						
						VoTplExcelField vtobj = new VoTplExcelField();
						List<VoTplExcelField> extraObjs = new ArrayList<VoTplExcelField>();
						extraObjs.add(0, vtobj);
						for (int i = 0, len = childs.getLength(); i < len; i++) 
						{
							Node child = childs.item(i);
							if (child instanceof Element) 
							{
								if (child.getNodeName().equals("field-cell"))
								{
									vtobj.setFieldCell(child.getFirstChild().getNodeValue());
								}
								else if (child.getNodeName().equals("field-text")) 
								{
									String nodeValue = child.getFirstChild().getNodeValue();
									String[] multipleNodeValues = nodeValue.split(",");
									int index = 0;
									for (String fieldName : multipleNodeValues)
									{
										if (index > 0)
										{
											VoTplExcelField extraObj = new VoTplExcelField();
											extraObj.setFieldCell(vtobj.getFieldCell());
											extraObjs.add(index, extraObj);
										}
										
										if (objcmp.containsKey(fieldName))
										{
											extraObjs.get(index).setFieldText(objcmp.get(fieldName).toString());
										}
										else 
										{
											for (String paramKey : objcmp.keySet())
											{
												if (fieldName.startsWith(paramKey))
												{
													extraObjs.get(index).setFieldText(objcmp.get(paramKey).toString() + 
															fieldName.substring(paramKey.length()));
													break;
												}
											}
										}
										
										index++;
									}
								} 
								else if (child.getNodeName().equals("field-key-data")) 
								{
									String[] keys = child.getFirstChild().getNodeValue().split(",");
									int index = 0;
									for (String key : keys)
									{
										extraObjs.get(index).setFieldKeyData(key);
										index++;
									}
									// vtobj.setFieldKeyData(child.getFirstChild().getNodeValue());
								} 
							}
						}
						
						for (VoTplExcelField vobj : extraObjs)
						{
							vtobjs.add(vobj);
							count++;
						}
					}
				}
				
				//ReflectUtils.getAllComponentsName(
				//		entry.getKey() + ".", entry.getValue())
				return vtobjs;
			}
			
			
			List<VoTplExcelField> vtobjs = new ArrayList<VoTplExcelField>();
			VoTplExcelField vtobj = new VoTplExcelField();
			if (node.getNodeName().equals("field-title")) 
			{
				vtobj.setTitle(true);
			}
			
			if (XMLParserUtils.getAttributeByName(node, "rowspan") != null)
			{
				vtobj.setFieldRowSpan(Integer.parseInt(XMLParserUtils.getAttributeByName(node, "rowspan")));
			}
			
			NodeList childs = node.getChildNodes();
			if (childs != null && childs.getLength() > 0) 
			{
				for (int i = 0, len = childs.getLength(); i < len; i++) 
				{
					Node child = childs.item(i);
					if (child instanceof Element) 
					{
						if (child.getNodeName().equals("field-cell")) 
						{
							vtobj.setFieldCell(child.getFirstChild().getNodeValue());
						} 
						else if (child.getNodeName().equals("field-text")) 
						{
							vtobj.setFieldText(child.getFirstChild().getNodeValue());
							if (child.getFirstChild().getNodeValue() != null && child.getFirstChild().getNodeValue().indexOf("${") > -1) 
							{
								vtobj.setParamInfieldText(true);
							}
						} 
						else if (child.getNodeName().equals("field-key-data")) 
						{
							vtobj.setFieldKeyData(child.getFirstChild().getNodeValue());
						} 
						else if (child.getNodeName().equals("field-key-comment")) 
						{
							vtobj.setFieldKeyComment(child.getFirstChild().getNodeValue());
						} 
						else if (child.getNodeName().equals("field-description")) 
						{
							vtobj.setFieldDescription(child.getFirstChild().getNodeValue());
						}
					}
				}
				
				vtobjs.add(vtobj);
				return vtobjs;
			}
		}
		return null;
	}
	
	public boolean isTitle() 
	{
		return isTitle;
	}
	
	public void setTitle(boolean isTitle) 
	{
		this.isTitle = isTitle;
	}
	
	public String getFieldCell() 
	{
		return fieldCell;
	}
	
	public void setFieldCell(String fieldCell) 
	{
		this.fieldCell = fieldCell;
	}
	
	public String getFieldText() 
	{
		return fieldText;
	}
	
	public void setFieldText(String fieldText) 
	{
		this.fieldText = fieldText;
	}
	
	public String getFieldKeyData() 
	{
		return fieldKeyData;
	}
	
	public void setFieldKeyData(String fieldKeyData) 
	{
		this.fieldKeyData = fieldKeyData;
	}
	
	public String getFieldKeyComment()
	{
		return fieldKeyComment;
	}
	
	public void setFieldKeyComment(String fieldKeyComment) 
	{
		this.fieldKeyComment = fieldKeyComment;
	}
	
	public String getFieldDescription() 
	{
		return fieldDescription;
	}
	
	public void setFieldDescription(String fieldDescription) 
	{
		this.fieldDescription = fieldDescription;
	}

	public void setParamInfieldText(boolean paramInfieldText) 
	{
		this.paramInfieldText = paramInfieldText;
	}

	public boolean isParamInfieldText() 
	{
		return paramInfieldText;
	}

	public void setFieldRowSpan(int fieldRowSpan) 
	{
		this.fieldRowSpan = fieldRowSpan;
	}

	public int getFieldRowSpan()
	{
		return fieldRowSpan;
	}
	
}
